package cz.muni.fi.pa165.musiclibrary.impl.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;

import org.apache.commons.lang3.Validate;
import org.springframework.transaction.annotation.Transactional;

import cz.muni.fi.pa165.musiclibrary.impl.database.dao.ISongDAO;
import cz.muni.fi.pa165.musiclibrary.impl.database.entity.ISong;
import cz.muni.fi.pa165.musiclibrary.api.service.ISongService;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IAlbumDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IArtistDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IGenreDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.ISongDTO;
import cz.muni.fi.pa165.musiclibrary.impl.service.dto.translator.AlbumDTOTranslator;
import cz.muni.fi.pa165.musiclibrary.impl.service.dto.translator.ArtistDTOTranslator;
import cz.muni.fi.pa165.musiclibrary.impl.service.dto.translator.GenreDTOTranslator;
import cz.muni.fi.pa165.musiclibrary.impl.service.dto.translator.SongDTOTranslator;

/**
 *
 * @author Martin Majlath 2012-11-03T00:12:30+0100
 */
@Transactional
public final class SongService implements ISongService {

    private ISongDAO songDao;

    public SongService(final ISongDAO songDao) {
        this.songDao = songDao;
    }

    @Override
    public void create(ISongDTO song, String userName) {
        Validate.isTrue(song != null,"Song should not be null");
        final ISong entity = SongDTOTranslator.translateFromDTO(song);
        this.songDao.create(entity);
    }

    @Override
    public void update(ISongDTO song, String userName) {
        Validate.isTrue(song != null,"Song should not be null");
        final ISong entity = SongDTOTranslator.translateFromDTO(song);
        this.songDao.update(entity);
    }

    @Override
    public void delete(ISongDTO song, String userName) {
        Validate.isTrue(song != null,"Song should not be null");
        final ISong entity = SongDTOTranslator.translateFromDTO(song);
        this.songDao.delete(entity);
    }

    @Override
    public ISongDTO getById(Long id) {
        Validate.isTrue(id != null,"Id should not be null");
        final ISong entity = this.songDao.getById(id);
        return SongDTOTranslator.translateToDTO(entity);
    }

    @Override
    public List<ISongDTO> getAll() {
        final List<ISong> songs = this.songDao.getAll();
        return this.translateSongs(songs);
    }

    @Override
    public List<ISongDTO> getByAlbum(IAlbumDTO album) {
        Validate.isTrue(album != null,"Album should not be null");
        final List<ISong> songs = this.songDao.getByAlbum(AlbumDTOTranslator.translateFromDTO(album));
        return this.translateSongs(songs);
    }

    @Override
    public List<ISongDTO> getByArtist(IArtistDTO artist) {
        Validate.isTrue(artist != null,"Artist should not be null");
        final List<ISong> songs = this.songDao.getByArtist(ArtistDTOTranslator.translateFromDTO(artist));
        return this.translateSongs(songs);
    }

    @Override
    public List<ISongDTO> getByGenre(IGenreDTO genre) {
        Validate.isTrue(genre != null,"Genre should not be null");
        final List<ISong> songs = this.songDao.getByGenre(GenreDTOTranslator.translateFromDTO(genre));
        return this.translateSongs(songs);
    }

    @Override
    public List<ISongDTO> getByTitle(String title) {
        Validate.isTrue(title != null,"Title should not be null");
        final List<ISong> songs = this.songDao.getByTitle(title);
        return this.translateSongs(songs);
    }

    /**
     * Translates a list of entity objects to DTO objects.
     *
     * @param songs Songs to translate.
     * @return Translated DTO objects.
     */
    @Nonnull
    private List<ISongDTO> translateSongs(final List<ISong> songs) {
        final List<ISongDTO> dtos = new ArrayList<ISongDTO>(songs.size());
        for (final ISong song : songs) {
            final ISongDTO dto = SongDTOTranslator.translateToDTO(song);
            dtos.add(dto);
        }
        return dtos;
    }
}